<?php


namespace api\modules\app\services;


use api\modules\app\models\MetaArea;
use api\modules\app\models\Qrcode;
use api\modules\app\models\QrcodeBind;
use api\modules\app\models\TypeSync;
use api\modules\app\models\Unit;

class ImportUnitService
{
    private $errMsg;

    private $lineErrMsg;

    public $districtMap;

    public $streetMap;

    public $typeSyncMap;

    public function getErrMsg()
    {
        return $this->errMsg;
    }

    public function import2($data)
    {
        $errCodes = [];
        $streetNames = MetaArea::find()->select(['name'])->where(['status' => 1, 'parent_id' => 6])->column();

        $streetMap = MetaArea::find()->where(['status' => 1, 'parent_id' => 6])->indexBy('name')->asArray()->all();


        $count = 0;

        foreach ($data as $v) {
            $eu = Unit::find()->where(['status' => 1, 'type' => Unit::TYPE_UNIT, 'outer_code' => $v['编号']])->one();
            if (!empty($eu)) {
                continue;
            }
            $location = UnitService::fillCood(['lat' => $v['纬度'], 'lng' => $v['经度']]);

            $streetName = '';
            foreach ($streetNames as $v1) {
                if (strpos($v['地址'], $v1) !== false) {
                    $streetName = $v1;
                    break;
                }
            }

            $model = new Unit();
            $model->type = Unit::TYPE_UNIT;
            $model->unit_code = '';
            $model->outer_code = $v['编号'];
            $model->address = $v['地址'];
            $model->other_dep = $v['辖区队站'];
            $model->channel = 2;
            $model->audit_state = 2; //审核通过
            $model->state = 1; //正常
            $model->ctime = 1695616275;
            $model->utime = 1695616275;
            if (!empty($v['一级部门'])) {
                $model->dep_code = $v['一级部门'];
            }

            //地区
            $model->district_code = '06';
            if (isset($streetMap[$streetName])) {
                $model->street_code = $streetMap[$streetName]['code'];
            }

            $model->name = '消火栓(专业)';
            $model->name_code = 'S17-01';
            $model->event_type1 = '事件';
            $model->event_type1_code = 'S';
            $model->event_type2 = '消防专业检查';
            $model->event_type2_code = 'S17';
            $model->event_type3 = '消火栓(专业)';
            $model->event_type3_code = 'S17-01';


            //坐标
            $model->lat = $v['纬度'];
            $model->lng = $v['经度'];
            $model->lat_cd = $location['lat_cd'];
            $model->lng_cd = $location['lng_cd'];
            $model->lat_gcj = $location['lat_gcj'];
            $model->lng_gcj = $location['lng_gcj'];

            $p['type'] = $model->type;
            $p['name_code'] = $model->name_code;
            $p['district_code'] = $model->district_code;
            $p['street_code'] = $model->street_code;

            $unitCode = UnitService::generateCode($p);
            $model->unit_code = $unitCode;

            if ($model->save()) {
                $count++;
            } else {
                $errCodes[] = $model->unit_code;
            }
        }

        return [$count, $errCodes];
    }

    public function import($data, $params)
    {
        $valid = isset($params['valid']) ? $params['valid'] : 1;
        $data = $this->trimAll($data);

        $this->formatData($data);

        //status=1全部成功 2-失败 3-部分成功
        $result = [
            'status' => 1,
            'errMsg' => '',
            'errLine' => [], //['line'=>'2','msg'=>'所属街道不能为空',]
        ];

        if (empty($data)) {
            $result['status'] = 2;
            $result['errMsg'] = '导入表格不能为空';
            return $result;
        }

        if (count($data) > 500) {
            $result['status'] = 2;
            $result['errMsg'] = '最多导入500个';
            return $result;
        }

        if (false === $this->checkTitle($data)) {
            $result['status'] = 2;
            $result['errMsg'] = $this->errMsg;
            return $result;
        }

        if (false === $this->checkOuterCode($data)) {
            $result['status'] = 2;
            $result['errMsg'] = $this->errMsg;
            return $result;
        }

        //需要验证后导入
        if ($valid) {
            $errLine = $this->checkData($data);
            if (!empty($errLine)) {
                $result['status'] = 3;
                $result['errLine'] = $errLine;
                return $result;
            }
        }

        //直接导入
        $successCount = 0;
        $failCount = 0;
        foreach ($data as $row) {
            if (false === $this->importRow($row)) {
                $failCount++;
            } else {
                $successCount++;
            }
        }
        $result['count'] = ['successCount' => $successCount, 'failCount' => $failCount];
        $result['errMsg'] = "导入成功{$successCount}个，导入失败{$failCount}个";
        return $result;
    }

    public function checkOuterCode($data)
    {
        $outerCodes = [];
        foreach ($data as $row) {
            $outerCode = $row['设施编码'];
            if (empty($outerCode)) {
                continue;
            }
            if (in_array($outerCode, $outerCodes)) {
                $this->errMsg = "{$outerCode}设施编码重复";
                return false;
            }
            $outerCodes[] = $outerCode;
        }

        return true;
    }

    public function formatData($data)
    {
        $districtNames = array_column($data, '所属区');
        $streetNames = array_column($data, '所属街道');

        $this->districtMap = MetaArea::find()->select(['code'])->where(['category' => '区', 'name' => $districtNames])->indexBy('name')->column();
        $this->streetMap = MetaArea::find()->select(['code'])->where(['category' => '街道', 'name' => $streetNames])->indexBy('name')->column();
        $this->typeSyncMap = TypeSync::find()->select(['*'])->where(['status' => 1])->indexBy('name')->asArray()->all();
    }

    public function trimAll($data)
    {
        $result = [];
        foreach ($data as $k1 => $v1) {
            foreach ($v1 as $k2 => $v2) {
                $result[$k1][$k2] = trim($v2);
            }
        }

        return $result;
    }

    public function checkTitle($data)
    {
        //表头不正确
        $titles = ['设施编码', '设施名称', '管理部门', '二级管理部门', '所属区', '所属街道', '设施位置', '经度（wgs84）', '纬度（wgs84）'];
        $importTitles = array_keys($data[0]);
        $diff = array_diff($titles, $importTitles);
        if (!empty($diff)) {
            $this->errMsg = '导入表头不正确';
            return false;
        }

        return true;
    }

    public function checkData($data)
    {
        $result = [];
        $line = 2;
        foreach ($data as $row) {
            if (false === $this->checkRow($row)) {
                $result[] = ['line' => $line, 'msg' => $this->lineErrMsg];
            }

            $line++;
        }

        return $result;
    }

    public function checkRow($row)
    {
        $requireFields = ['设施名称', '所属区', '所属街道', '设施位置'];
        foreach ($requireFields as $field) {
            if (!isset($row[$field]) || empty($row[$field])) {
                $this->lineErrMsg = $field . '不能为空';
                return false;
            }
        }
        $district = MetaArea::findOne(['category' => '区', 'name' => $row['所属区']]);
        if (empty($district)) {
            if (!isset($row[$field]) || empty($row[$field])) {
                $this->lineErrMsg = '所属区不正确';
                return false;
            }
        }
        $street = MetaArea::findOne(['category' => '街道', 'name' => $row['所属街道'], 'parent_id' => $district->id]);
        if (empty($street)) {
            $this->lineErrMsg = '所属街道不正确';
            return false;
        }

        if (!isset($this->typeSyncMap[$row['设施名称']])) {
            $this->lineErrMsg = '设施名称不正确';
            return false;
        }

        if (!empty($row['设施编码'])) {
            $unit = Unit::findOne(['status' => 1, 'outer_code' => $row['设施编码']]);
            if (!empty($unit)) {
                $this->lineErrMsg = '设施编码已经存在';
                return false;
            }
        }
    }

    public function importRow($row)
    {
        $currentTime = time();
        if (false === $this->checkRow($row)) {
            return false;
        }

        $lat = $row['纬度（wgs84）'];
        $lng = $row['经度（wgs84）'];
        $location = UnitService::fillCood(['lat' => $lat, 'lng' => $lng]);

        $model = new Unit();
        $model->type = Unit::TYPE_UNIT;
        $model->unit_code = '';
        $model->outer_code = $row['设施编码'];
        $model->address = $row['设施位置'];
        $model->dep_code = $row['管理部门'];
        $model->other_dep = $row['二级管理部门'];
        $model->channel = 2;
        $model->audit_state = 2; //审核通过
        $model->state = 1; //正常
        $model->ctime = $currentTime;
        $model->ctime = $currentTime;
        $model->district_code = $this->districtMap[$row['所属区']];
        $model->street_code = $this->streetMap[$row['所属街道']];

        $typeSync = $this->typeSyncMap[$row['设施名称']];


        $model->name = $typeSync['name'];
        $model->name_code = $typeSync['name_code'];
        $model->event_type1 = $typeSync['event_type1'];
        $model->event_type1_code = $typeSync['event_type1_code'];
        $model->event_type2 = $typeSync['event_type2'];
        $model->event_type2_code = $typeSync['event_type2_code'];
        $model->event_type3 = $typeSync['event_type3'];
        $model->event_type3_code = $typeSync['event_type3_code'];

        //坐标
        $model->lat = $lat;
        $model->lng = $lng;
        $model->lat_cd = $location['lat_cd'];
        $model->lng_cd = $location['lng_cd'];
        $model->lat_gcj = $location['lat_gcj'];
        $model->lng_gcj = $location['lng_gcj'];

        $p['type'] = $model->type;
        $p['name_code'] = $model->name_code;
        $p['district_code'] = $model->district_code;
        $p['street_code'] = $model->street_code;

        $unitCode = UnitService::generateCode($p);
        $model->unit_code = $unitCode;

        if ($model->save()) {
            return true;
        } else {
            return false;
        }
    }

    public function importFire($data)
    {
        $data = $this->trimAll($data);

        $districtNames = array_column($data, '区划');
        $streetNames = array_column($data, '街道');
        $districtMap = MetaArea::find()->select(['code'])->where(['category' => '区', 'name' => $districtNames])->indexBy('name')->column();
        $streetMap = MetaArea::find()->select(['code'])->where(['category' => '街道', 'name' => $streetNames])->indexBy('name')->column();

        foreach ($data as $row) {
            $unitCode = $row['原管理编码'];
            if (!empty($unitCode)) {
                if (substr($unitCode, 0, 1) == '?') {
                    //去掉问号
                    $unitCode = substr($unitCode, 1);
                }

                $model = Unit::find()->where(['unit_code' => $unitCode])->one();
                if (empty($model)) {
                    continue;
                }
                //编辑
                $model->industry_code = $row['新行业管理编码'];
                $model->outer_code = $row['外部展示标识'];
                $model->city_unique_code = $row['全市唯一编码'];
                $model->other_dep = $row['主管部门'];
                $model->save();
            } else {
                //外区，查外部展示标识
                $model = Unit::find()->where(['outer_code' => $row['外部展示标识']])->one();
                if (empty($model)) {
                    //新增
                    $model = new Unit();

                    $model->type = Unit::TYPE_UNIT;
                    $model->name = '消火栓(专业)';
                    $model->name_code = 'S17-01';
                    $model->event_type1 = '事件';
                    $model->event_type1_code = 'S';
                    $model->event_type2 = '消防专业检查';
                    $model->event_type2_code = 'S17';
                    $model->event_type3 = '消火栓(专业)';
                    $model->event_type3_code = 'S17-01';
                    $model->address = $row['地址'];

                    $p['type'] = $model->type;
                    $p['name_code'] = $model->name_code;
                    $p['district_code'] = $model->district_code;
                    $p['street_code'] = $model->street_code;

                    $code = UnitService::generateCode($p);
                    $model->unit_code = $code;
                }

                $model->industry_code = $row['新行业管理编码'];
                $model->outer_code = $row['外部展示标识'];
                $model->city_unique_code = $row['全市唯一编码'];
                $model->other_dep = $row['主管部门'];
                //修改区街道
                $model->district_code = $districtMap[$row['区划']];
                $model->street_code = $streetMap[$row['街道']];
            }

            $model->save();
        }
    }

    /**
     * 导入市级excel
     */
    public function importCityFire($data)
    {
        $data = $this->trimAll($data);

        $districtNames = array_column($data, '区划');
        $districtMap = MetaArea::find()->select(['code'])->where(['category' => '区', 'name' => $districtNames])->indexBy('name')->column();

        foreach ($data as $row) {
            $unitCode = $row['行业管理编码'];
            $model = Unit::find()->where(['unit_code' => $unitCode])->one();

            if (empty($model)) {
                //新增
                $model = new Unit();
                $model->type = Unit::TYPE_UNIT;
                $model->district_code = $districtMap[$row['区划']];
                $model->unit_code = $unitCode;
                $model->industry_code = $unitCode;
                $model->city_unique_code = $row['全市唯一编码'];
                $model->has_bind = 1;
                $model->status = 1; //有效
                $model->audit_state = 2; //审核通过
                $model->name = '消火栓(专业)';
                $model->name_code = 'S17-01';
                $model->event_type1 = '事件';
                $model->event_type1_code = 'S';
                $model->event_type2 = '消防专业检查';
                $model->event_type2_code = 'S17';
                $model->event_type3 = '消火栓(专业)';
                $model->event_type3_code = 'S17-01';
            } else {
                //编辑
            }

            $model->address = $row['地址'];
            $model->dep_code = $row['权属单位'];
            $model->other_dep = $row['主管部门'];
            $model->qrcode = $row['码值'];
            $cdAddressInfo = $this->getCdLocationByAddress($row['地址']);

            if (isset($cdAddressInfo['data']['坐标X']) && !empty($cdAddressInfo['data']['坐标X'])) {
                $cood = UnitService::fillCood(['lat_cd' => $cdAddressInfo['data']['坐标Y'], 'lng_cd' => $cdAddressInfo['data']['坐标X']]);
                if (isset($cood['lat']) && !empty($cood['lat'])) {
                    $model->lat = $cood['lat'];
                    $model->lng = $cood['lng'];
                    $model->lat_cd = $cood['lat_cd'];
                    $model->lng_cd = $cood['lng_cd'];
                    $model->lat_gcj = $cood['lat_gcj'];
                    $model->lng_gcj = $cood['lng_gcj'];
                }
            }

            //保存unit部件表
            $model->save();

//            $qrcode = Qrcode::find()->where(['code' => $model->qrcode])->one();
//            if (empty($qrcode)) {
//                $qrcode = new Qrcode();
//                $qrcode->code = $model->qrcode;
//                $qrcode->save();
//            }
//
//            $qrcodeBind = QrcodeBind::find()->where(['qrcode' => $model->qrcode])->one();
//            if (empty($qrcodeBind)) {
//                $qrcodeBind = new QrcodeBind();
//                $qrcodeBind->qrcode = $model->qrcode;
//                $qrcodeBind->type = Unit::TYPE_UNIT;
//            }
//            $qrcodeBind->unit_code = $unitCode;
//            $qrcodeBind->save();
        }
    }

//DROP INDEX `code`;
//ALTER TABLE `unit`
//MODIFY COLUMN `qrcode` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL AFTER `utime`;

//ALTER TABLE `qrcode`
//MODIFY COLUMN `code` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL AFTER `id`;

//ALTER TABLE qrcode_bind`
//MODIFY COLUMN `qrcode` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' AFTER `id`;

    public function getCdLocationByAddress($address)
    {
        $districtNames = MetaArea::find()->select('name')->where(['category' => '区', 'parent_id' => 0])->column();
        $str = str_replace('上海市', '', $address);
        $str = str_replace('上海', '', $str);

        foreach ($districtNames as $dname) {
            $str = str_replace($dname, '', $str);
        }

        $str = urlencode($str);
        $url = "http://10.212.3.225:18104/CoordReverse/mapTransform/coordinateByAddress?ruleType=0&address={$str}";
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);

        $output = curl_exec($curl);
        curl_close($curl);
        $output = json_decode($output, true);
        return $output;
    }

}
